﻿#include <stdio.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkPlaneSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkActor2D.h>
#include <vtkTransform.h>

using namespace std;
void printPoint(const char *comment, double *p);

void printPoint(const char *comment, double *p)
{
    std::cout << comment << ": " << p[0] << " "
              << p[1] << " " << p[2] << std::endl;
}

void rotateActor(vtkSmartPointer<vtkActor> actor)
{
    double oldNormal[3] = { 0, -1, 0 };

    printf( "oldNormal: %lf, %lf, %lf\n", oldNormal[0], oldNormal[1], oldNormal[2] );
    // oldNormal: 0.000000, -1.000000, 0.000000

    actor->RotateZ( 90 );

    vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
    transform->SetMatrix( actor->GetMatrix() );
    double *newNormal = transform->TransformDoubleVector( oldNormal );
    printf( "newNormal: %lf, %lf, %lf\n", newNormal[0], newNormal[1], newNormal[2] );
    // newNormal: 1.000000, -0.000000, 0.000000
    fflush( stdout );
}

int main()
{
    vtkSmartPointer<vtkPlaneSource> plane =
            vtkSmartPointer<vtkPlaneSource>::New();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection( plane->GetOutputPort() );

    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper( mapper );
    double *origin = actor->GetOrigin();
    // actor->AddPosition( 1, 1, 1 );

    printPoint("orgin", origin);
//    printf( "origin: %lf, %lf, %lf\n", origin[0], origin[1], origin[2] );
    // origin: 0.000000, 0.000000, 0.000000


    /////////////
    /// \brief renderer
    ///
    actor->AddPosition( 1, 1, 1 );
    // origin: 0.000000, 0.000000, 0.000000
    origin =  actor->GetOrigin();
    printPoint("orgin(after AddPosition)", origin);

    vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
    transform->SetMatrix( actor->GetMatrix() );
    double *newPos = transform->TransformDoublePoint( origin[0], origin[1], origin[2] );
    printPoint("newPos(after AddPosition)", newPos);
    // newPos: 1.000000, 1.000000, 1.000000


    rotateActor(actor);
    /// end

    double bounds[6];
    actor->GetBounds(bounds);
    std::cout << "actor bounds:" << bounds[0] << "," << bounds[1] << "," << bounds[2] << "," << bounds[3]
              << "," << bounds[4] << "," << bounds[5]<< std::endl;

    plane->GetOutput()->GetBounds(bounds);
    std::cout << "plane bounds:" << bounds[0] << "," << bounds[1] << "," << bounds[2] << "," << bounds[3]
              << "," << bounds[4] << "," << bounds[5]<< std::endl;

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground( 0, 0, 0 );

    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();



    return 0;
}
